﻿using Furion;
using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.UnifyResult;
using JoyAdmin.Core;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TulingMember.Application.Dto;
using TulingMember.Core; 
using Yitter.IdGenerator;

namespace TulingMember.Application
{
    public class ProductService : IDynamicApiController
    {
        private readonly ILogger _logger; 
        private readonly IRepository<cts_Product> _productRepository;
        private readonly IRepository<cts_ProductType> _producttypeRepository;
        private readonly IRepository<cts_Unit> _unitRepository;
        private readonly IRepository<cts_ProductLog> _productlogRepository;
        public ProductService(ILogger logger 
            , IRepository<cts_Product> productRepository
            , IRepository<cts_ProductType> producttypeRepository
            , IRepository<cts_Unit> unitRepository
            , IRepository<cts_ProductLog> productlogRepository)
        {
            _logger = logger; 
            _productRepository = productRepository;
            _producttypeRepository = producttypeRepository;
            _unitRepository = unitRepository;
            _productlogRepository = productlogRepository;
        }

        #region 商品分类
        /// <summary>
        /// 列表
        /// </summary> 
        public List<cts_ProductType> SearchProductType(BaseInput input)
        {
            var search = _producttypeRepository.AsQueryable();
            if (!string.IsNullOrEmpty(input.keyword))
            {
                search = search.Where(m => m.Name.Contains(input.keyword));
            }
            return search.OrderBy(m=>m.Sort).ToList();
        }
        /// <summary>
        /// 获取树形商品分类
        /// </summary>
        /// <returns></returns>
        public List<TreeProductTypeDto> GetTreeProductType()
        {
            var list = _producttypeRepository.AsQueryable().Select(u => u.Adapt<TreeProductTypeDto>()).ToList();
            return new TreeBuildUtil<TreeProductTypeDto>().Build(list);
        }




        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine("product")]
        [UnitOfWork]
        public void SaveProductType(cts_ProductType input)
        {
            var oldCount = _producttypeRepository.Where(m => m.Name.Equals(input.Name) && m.Id != input.Id).Count();
            if (oldCount > 0)
            {
                throw Oops.Bah("商品分类已存在，请检查").StatusCode(ErrorStatus.ValidationFaild);
            }
            input.ParentIds = CreateNewPids(input.ParentId);
            if (input.Id > 0)
            {
                _producttypeRepository.Update(input);
            }
            else
            {
                _producttypeRepository.Insert(input);
            }

        }
        /// <summary>
        /// 删除
        /// </summary>  
        [SecurityDefine("product")]
        public void DeleteProductType(long id)
        {
            var productCount= _productRepository.Where(m => m.TypeId == id).Count();
            if (productCount > 0)
            {
                throw Oops.Bah("该分类下存在商品，请检查").StatusCode(ErrorStatus.ValidationFaild);
            }
            _producttypeRepository.FakeDelete(id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
       [NonAction]
        private string CreateNewPids(long pid)
        {
            if (pid == 0L)
            {
                return "[0],";
            }
            else
            {
                var pmenu = _producttypeRepository.DetachedEntities.FirstOrDefault(u => u.Id == pid);
                return pmenu.ParentIds + "[" + pid + "],";
            }
        }
        #endregion
        #region 商品管理
        /// <summary>
        /// 商品列表
        /// </summary> 
        public PagedList<ProductDto> SearchProduct(BaseInput input)
        {
            var search = _productRepository.AsQueryable();
                         
                          
            if (!string.IsNullOrEmpty(input.keyword))
            {
                search = search.Where(m => m.Code.Contains(input.keyword)
                || m.Name.Contains(input.keyword) || m.Specification.Contains(input.keyword));
            }
            if (input.typeid > 0)
            {
                var typeIds = _producttypeRepository.Where(m => m.ParentIds.Contains(input.typeid.ToString())).Select(m => m.Id).ToList();
                typeIds.Add(input.typeid);
                search = search.Where(m => typeIds.Contains(m.TypeId));
            } 

            var search2= from a in search
                         join b in _producttypeRepository.AsQueryable() on a.TypeId equals b.Id
                         select DtoHelper.TransProductDto(a, b);
            return search2.ToPagedList(input.page, input.size);
        }
        /// <summary>
        /// 保存商品
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine("product")]
        [UnitOfWork]
        public void SaveProduct(cts_Product input)
        {
            var oldCount= _productRepository.Where(m=>m.Name.Equals(input.Name)&&m.Id!=input.Id)
                .Where(!string.IsNullOrEmpty(input.Code), m => m.Code.Equals(input.Code) && m.Id != input.Id).Count();
            if (oldCount>0)
            {
                throw Oops.Bah("名称或编码已存在，请检查").StatusCode(ErrorStatus.ValidationFaild);
            }
            if (input.Id > 0)
            {
                _productRepository.UpdateExclude(input,new string[] { nameof(input.Num)});
            }
            else {
                input.Id = YitIdHelper.NextId();
                _productRepository.Insert(input);
                if (input.Num>0)
                {
                    _productlogRepository.Insert(new cts_ProductLog
                    {
                        ProductId = input.Id,
                        ProductName = input.Name,
                        ChangeNum = input.Num,
                        NewNum = input.Num,
                        TagName = "期初库存",
                        TagType = ProductChangeTag.None
                    });
                }
            }
            if (!string.IsNullOrEmpty(input.Unit))
            {
                var unitCount = _unitRepository.Where(m => m.Name.Equals(input.Unit)).Count();
                if (unitCount == 0)
                {
                    _unitRepository.Insert(new cts_Unit { Name=input.Unit});
                }
            }
            
        }
        /// <summary>
        /// 删除商品
        /// </summary>  
        [SecurityDefine("product")]
        public void DeleteProduct(long id)
        {
            _productRepository.FakeDelete(id);
        }

        /// <summary>
        /// 产品出入库明细
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedList<cts_ProductLog> SearchProductLog(BaseInput input)
        {

            var search = _productlogRepository.Where(m => m.ProductId == input.productid);
            if (input.sdate != null)
            {
                search = search.Where(m => m.CreatedTime >= input.sdate);
            }
            if (input.edate != null)
            {
                var edate = input.edate?.AddDays(1).Date;
                search = search.Where(m => m.CreatedTime < edate);
            }
            search = search.OrderByDescending(m => m.CreatedTime);
            var data = search.ToPagedList(input.page, input.size);
            return data;
        }
        /// <summary>
        /// 盘点
        /// </summary> 
        [SecurityDefine("productcheck")]
        [UnitOfWork]
        public Task SaveProductCheck(ProductCheckDto dto)
        {
            var oldentity = _productRepository.FindOrDefault(dto.Id);
            if (oldentity.Num != dto.CheckNum )  
            {
                //变更记录
                cts_ProductLog log = new cts_ProductLog
                {
                    Id = YitIdHelper.NextId(),
                    ProductId = oldentity.Id,
                    ProductName = oldentity.Name, 
                    OldNum = oldentity.Num,
                    ChangeNum = dto.CheckNum - oldentity.Num,
                    NewNum = dto.CheckNum,
                    TagType = ProductChangeTag.Check,
                    TagName = "盘点",
                };
                _productlogRepository.Insert(log); 
                oldentity.Num = dto.CheckNum; 
            }
            return Task.CompletedTask;
        }
        #endregion
        #region 计量单位

        /// <summary>
        /// 列表
        /// </summary> 
        public List<cts_Unit> SearchUnit(BaseInput input)
        {
            var search = _unitRepository.AsQueryable();
            if (!string.IsNullOrEmpty(input.keyword))
            {
                search = search.Where(m => m.Name.Contains(input.keyword));
            }
            return search.OrderBy(m => m.Sort).ToList();
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine("product")]
        [UnitOfWork]
        public void SaveUnit(cts_Unit input)
        {
            var oldCount = _unitRepository.Where(m => m.Name.Equals(input.Name) && m.Id != input.Id).Count();
            if (oldCount > 0)
            {
                throw Oops.Bah("单位已存在，请检查").StatusCode(ErrorStatus.ValidationFaild);
            }
          
            if (input.Id > 0)
            {
                _unitRepository.Update(input);
            }
            else
            {
                _unitRepository.Insert(input);
            }

        }
        /// <summary>
        /// 删除
        /// </summary>  
        [SecurityDefine("product")]
        public void DeleteUnit(long id)
        {
            _unitRepository.Delete(id);
        }
        #endregion


    }
}
